﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PlanetViewer
{
    /// <summary>
    /// A Planet...What?
    /// </summary>
    public class Planet
    {
        
        private int _radius;
        /// <summary>
        /// The radius of the planet, measured in (no idea).
        /// </summary>
        public int Radius { get { return _radius; } }
       
        private int _depth;
        /// <summary>
        /// Depth of the planet, measured from (surface?).
        /// </summary>
        public int Depth { get { return _depth; } }

        private int _nLayers;
        /// <summary>
        /// Gets the layer count
        /// </summary>
        public int nLayers { get { return _nLayers; } }

        private int _nSpines;
        /// <summary>
        /// Gets the spine count
        /// </summary>
        public int nSpines { get { return _nSpines; } }

        private float _spineAng;
        public float SpineAngle { get { return _spineAng; } }

        /// <summary>
        /// Gets or Sets the Terrain that defines the planets surface.
        /// </summary>
        public Terrain Terrain;

        public PlanetViewer _plViewer;
        
        /// <summary>
        /// Creates the planet.
        /// </summary>
        /// <param name="radius">The radius of the planet</param>
        /// <param name="depth">The depth of the Terrain</param>
        /// <param name="nlayers">The number of layers</param>
        /// <param name="roughness">The roughness of Terrain (values above 1.0f not recommended)</param>
        public Planet(PlanetViewer plviewer, int radius, int explorableDepth, int nlayers, float roughness = 0.5f)
        {
            this._plViewer = plviewer;

            this._radius = radius;
            this._depth = explorableDepth - explorableDepth % 2;
            this._nLayers = nlayers;
            
            float layerdepth = this._depth / this._nLayers;

            this._nSpines = (int)((float)Math.Round(2 * MathHelper.Pi * (this._radius - this._depth / 2) / layerdepth));
            
            this._spineAng = 2 * MathHelper.Pi / this._nSpines;



            this.Terrain = new Terrain(this, this._nSpines);

            this.Terrain.SetupHeightmap();



            float spineArc = this._spineAng * (float)this._radius;

            // Visible Arc: the proportion of the planet included in the TerrainDrawMask at the default zoom level (CamZ = -100).
            // Domain: 0 to 2 Pi.
            float visibleArc = (5.0f * (float)this.Depth) / spineArc;

            this.Terrain.DrawMask = new TerrainDrawMask(Terrain, (int)Math.Ceiling(visibleArc));
        }
    }
}
